const { resolve } = require('path');
// 引入插件
const HtmlWebpackPlugin = require('Html-webpack-plugin'); // 作用 打包html
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 作用 将js中的css提取出来
const cssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin'); // 作用：将css压缩

// 设置nodejs环境变量 做兼容处理
process.env.NODE_ENV = 'development'; // 开发依赖时做css兼容需要设置node的环境为开发环境 不然默认为生产环境

module.exports = {
  // 1、入口
  entry: './src/main.js',
  // 2、出口
  output: {
    // 名称
    filename: 'js/index.js',
    // 绝对路径下的 build文件夹
    path: resolve(__dirname, 'build'),
  },
  // 3、处理非js和json文件
  module: {
    rules: [
      // 13、js语法检查之eslint : 让代码风格统一规范 ：eslint eslint-loader
      // 注意：13.1：设置只检查自己写的源代码，第三方库不用检查
      // "eslintConfig": {
      //   "extends": "airbnb-base"
      // }
      // eslint-disable-next-line max-len
      // 13.2：设置检查规则：在package.json中eslint中设置 （推荐使用airbnb）->eslint-config-airbnb-base eslint eslint-plugin-import
      {
        test: /\.js$/,
        exclude: /node_modules/, // 排除第三方库
        loader: 'eslint-loader',
        options: {
          // 自动修复eslint错误
          fix: true,
        },
      },
      {
        // 14、js兼容性处理
        //   14.1：js基本兼容性处理：babel-loader @babel/preset-env
        //   14.2：全部js兼容性处理：@babel/polyfill
        //   14.3：按需做兼容性处理：按需加载：core-js
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,  // 排除第三方库
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'], // 预设：告诉babel怎么样做兼容性处理
            plugins: ['@babel/plugin-proposal-object-rest-spread']
          }
        }
      },
      // 处理css文件
      {
        test: /\.css$/i,
        use: [
          // 7、css兼容处理
          // eslint-disable-next-line max-len
          // MiniCssExtractPlugin.loader取代style-loader  MiniCssExtractPlugin的作用是将js中的css提取出来作为一个单独的文件
          MiniCssExtractPlugin.loader, // npm i mini-css-extract-plugin -D
          'css-loader',
          // css兼容性处理：postcss --> postcss-loader  postcss-preset-env 这两个包
          // 兼容写法一：使用默认配置
          // 'postcss-loader'
          // 兼容写法二：修改loader的配置
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [
                  ['postcss-preset-env'],
                ],
              },
            },
          },
        ],
      },
      // 8、处理less文件
      {
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader'],
      },
      // 9、处理图片文件
      {
        test: /\.(gif|png|jpg|jpge)/i,
        loader: 'url-loader',
        // 配置图片信息
        options: {
          limit: 8 * 1024, // 小于8kb转为base64格式代码
          name: '[hash:10].[ext]', // [hash:10]:取hash值前10位 [ext]：取文件原来的扩展名
          esModule: false,
          // outputPath:'img' 在匹配的（gif|png|jpg|jpeg）这些图片资源打包时会将其放在img文件夹中
        },
      },
      // 10、处理模板文件中手动引入的图片资源
      {
        test: /\.html$/,
        loader: 'html-loader',
      },
      // 11、打包其他资源（除了html、js、css以外的资源）
      {
        exclude: /\.(css|js|html|less)$/,
        loader: 'file-loader',
        options: {
          name: '[hash:10].[ext]',
          // outputPath:'media' 将其他资源打包放在media文件夹中
        },
      },
      // to do...
    ],
  },
  // 4、html 的打包默认文件 复制这个文件并且自动引入所有的依赖包
  plugins: [
    new HtmlWebpackPlugin({ // HtmlWebpackPlugin插件用于打包html
      template: './src/index.html',
      // 16、压缩html
      minify: {
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true
      }
    }),
    new MiniCssExtractPlugin({ // MiniCssExtractPlugin插件作用：将js中的css代码提取出来
      // 对输出的文件进行重命名
      filename: 'css/build.css',
    }),
    // 12、压缩css代码 ：css-minimizer-webpack-plugin
    // eslint-disable-next-line new-cap
    new cssMinimizerWebpackPlugin(), // 默认的配置足以将css压缩
  ],
  // 5、开发环境
  // mode: 'development',
  mode: 'production',
  // 15：压缩js：将开发环境设置为生产环境就

  // 6、开发服务器devServer：用来自动化（自动编译，自动打开浏览器，自动刷新浏览器）
  // 启动指令： npx webpack-dev-server
  devServer: {
    // 运行的目录 不是源代码目录
    static: {
      directory: resolve(__dirname, 'build'),
    },
    // 启动gzip压缩 让代码体积更小
    compress: true,
    port: 3000, // 指定端口号
    open: true, // 自动打开浏览器
  },
};

// 生产环境
// webpack ./src/index.js -o ./build --mode=development
// 开发环境
// webpack ./src/index.js -o ./build --mode=production

